pytorch版本RetinaFace人脸检测模型推理加速,去掉FPN第一层,不检测特别小的人脸框

您所在的位置:网站首页 百度人脸融合 参数 pytorch版本RetinaFace人脸检测模型推理加速,去掉FPN第一层,不检测特别小的人脸框

pytorch版本RetinaFace人脸检测模型推理加速,去掉FPN第一层,不检测特别小的人脸框

2023-02-11 22:30| 来源: 网络整理| 查看: 265

pytorch版本RetinaFace人脸检测模型推理加速_胖胖大海的博客-程序员秘密

pytorch版本RetinaFace人脸检测模型推理加速,去掉FPN第一层,不检测特别小的人脸框_胖胖大海的博客-程序员秘密

代码地址:GitHub - xxcheng0708/Pytorch_Retinaface_Accelerate: Retinaface get 80.99% in widerface hard val using mobilenet0.25.

         在之前的文章pytorch版本RetinaFace人脸检测模型推理加速中,介绍了如何从工程实现的角度来加速Pytorch版本的RetinaFace开源代码,上一次的优化点主要有以下两点:

        1、优化Prior的计算方式,提升连续处理相同分辨率图片的处理性能

        2、将数据预处理操作转换到GPU上处理

        上一次优化后的RetinaFace处理性能如下:

        RetinaFace整体结构表示如上图,在Backbone的基础上使用FPN进行特征融合,并在每种特征图上使用ContextModule模块提取更多的上下文信息,然后预测输出人脸置信度、bbox坐标框,以及人脸关键点坐标。如上图P2特征图的感受野最小,特征粒度最小,在此特征图上使用小的anchor检测小的人脸。如上图P5特征图的感受野最大,特征粒度最粗,在此特征图上使用大的anchor检测大的人脸。

        在本文中,从精简模型预测结果,丢弃小的人脸检测结果的角度对RetinaFace进行优化。通过前面的描述我们知道,RetinaFace里面采用了特征金字塔FPN,其中低层特征用来检测小的人脸,高层的特征用来检测大的人脸,但是如果下游任务是人脸识别任务的话,小的人脸对于人脸识别结果不论是在准确率还是召回率方面都没有太多正向的作用。所以在这种使用场景下可以把检测小的人脸这部分功能去掉,节省算力,还能提升一些模型的推理速度。同时,将原本代码中cpu版本的NMS操作换成torchvision中提供的GPU版本NMS来提速。

        先看一下精简FPN前后人脸检测速度的对比数据:

精简前(处理2000张720p的图片)

精简后(处理2000张720p的图片)

提升效果

Backbone

fps

总耗时(s)

平均耗时(ms)

fps

总耗时(s)

平均耗时(ms)

ResNet50

19.0 104.8 52.6 21.0 94.9 47.6

9.5%

MobileNet

60.3 33.1 16.5 76.1 26.2 13.1

20.6%

        另外再看一下精简FPN前后的人脸检测效果对比:

        FPN精简前:

        FPN精简后:

        下面以开源代码中提供的使用Resnet50作为backbone的模型为例,主要修改涉及到以下代码文件:

    1)、./models/retinaface.py

    2)、./models/net.py

    3)、./data/config.py

    4)、./utils/nms/py_gpu_nms.py

首先,看一下config.py配置文件 cfg_re50 = { 'name': 'Resnet50', 'min_sizes': [[16, 32], [64, 128], [256, 512]], 'steps': [8, 16, 32], 'variance': [0.1, 0.2], 'clip': False, 'loc_weight': 2.0, 'gpu_train': True, 'batch_size': 24, 'ngpu': 4, 'epoch': 100, 'decay1': 70, 'decay2': 90, 'image_size': 840, 'pretrain': True, 'return_layers': {'layer2': 1, 'layer3': 2, 'layer4': 3}, 'in_channel': 256, 'out_channel': 256 }

        其中,在上面的配置文件中,我们看到RetinaFace以Resnet50作为backbone,在backbone的layer2、layer3、layer4三个层进行FPN特征融合,min_sizes对应三个特征图上生成的anchor box的大小,steps分别分别对应三个特征图上的下采样倍数。min_sizes取值[16, 32]和steps取值8用来在低层特征图(如上面的P2)上面检测小的人脸框,所以我们可以把min_sizes里面的[16, 32]和steps里面的8去掉,得到如下的配置文件:

cfg_re50 = { 'name': 'Resnet50', 'min_sizes': [[64, 128], [256, 512]], 'steps': [16, 32], 'variance': [0.1, 0.2], 'clip': False, 'loc_weight': 2.0, 'gpu_train': True, 'batch_size': 24, 'ngpu': 4, 'epoch': 100, 'decay1': 70, 'decay2': 90, 'image_size': 840, 'pretrain': True, 'return_layers': {'layer2': 1, 'layer3': 2, 'layer4': 3}, 'in_channel': 256, 'out_channel': 256 } 其次,在修改了config.py配置文件之后,我们打算把三层的FPN特征融合改成两层的,取消分辨率最大的(用来检测小人脸)的那一层,所以要同步修改net.py里面的FPN模块,原始的FPN模块推理代码如下: class FPN(nn.Module): def __init__(self,in_channels_list,out_channels): super(FPN,self).__init__() leaky = 0 if (out_channels


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3